RefineKnotVect
1) The first test of the knot vector refinement algorithms is the case given in The NURBS Book's Figure 5.18-19.
The following program tests the knot vector refinement algorithms for curves by reproducing these plots.
program test_curve_refinement
use splines
use points
implicit none
integer, parameter :: wp = selected_real_kind(15,307)
logical, parameter :: T = .true.
logical, parameter :: F = .false.
type(cpt) :: cp(7)
real(wp) :: U(11),X(6)
type(curve) :: crv, new
cp(:)%x = [ 0.00_wp, 0.10_wp, 1.90_wp, 2.40_wp, 4.00_wp, 4.40_wp, 3.50_wp]
cp(:)%y = [ 0.20_wp, 2.30_wp, 2.50_wp, 0.00_wp, 0.00_wp, 1.50_wp, 3.00_wp]
U=[0.0_wp,0.0_wp,0.0_wp,0.0_wp,1.0_wp,2.0_wp,3.0_wp,4.0_wp,4.0_wp,4.0_wp,4.0_wp]
crv = spl(dim=2, pd=1, p=[3], kXi=U, cp=cp)
new = crv
X=[1.00_wp, 1.00_wp, 2.00_wp, 2.00_wp, 3.00_wp, 3.00_wp]
! plot the original curve with the control polygon by marking specified knot values (dots)
call crv%plot( plotCP=T, labelCP=T, plotElems=T, &
terminal='png', &
fname="test_F5.18a", &
title="The curve and its control polygon")
! plot the original bases by using 100 point
call crv%N(1)%plot( terminal='png', &
fname="test_F5.18b",&
title="The basis functions defined over \\{0,0,0,0,1,2,3,4,4,4,4\\}")
! refine knot vector
call new%RefineKnotVect(X=X)
! plot the new curve with the control polygon by marking specified knot values
call new%plot( plotCP=T, labelCP=T, plotElems=T, &
terminal='png', &
fname="test_F5.19a", &
title="The decomposed curve and its control polygon")
! plot the new bases by using 100 point
call new%N(1)%plot( fname="test_F5.19b",&
terminal='png', &
title="The basis functions after inserting knots 1, 2, and 3 two times each.")
end program test_curve_refinement
The program refines the curve's knot vector given in Figure 5.18(a). The basis functions of the initial curve are as seen in Figure 5.18(b). The refinement of the knot vector by the vector results in a curve split into its Bézier segments from these knot values. Figure 5.19 shows this new curve and corresponding basis functions. The resulting plots are as follow,
2) The second test of the knot vector refinement algorithms is the case given in The NURBS Book's Figure 5.17. This example shows midpoint knot refinements (a new knot is inserted at the midpoint of each knot span) to the surface shown in Figure 5.9. Refining knot vectors takes the control net closer to the surface, and in the limit state, the control net converges to the surface. It can be observed in this example.
The following program tests the knot vector refinement algorithms for surfaces by reproducing the cases given in Figure 5.17.
program test_surface_refinement
use splines
use points
implicit none
integer, parameter :: wp = selected_real_kind(15,307)
logical, parameter :: T = 1
logical, parameter :: F = 0
type(surface) :: S, surf1, surf2
type(cpt) :: scp(16)
real(wp) :: U(8), V(7), X(7), Y(6)
scp(:)%x = [ 1.0, 1.0, 1.0, 1.0, 0.2, 0.2, 0.2, 0.2, &
-0.2, -0.2, -0.2, -0.2, -1.0, -1.0, -1.0, -1.0]
scp(:)%y = [-1.0, -0.2, 0.2, 1.0, -1.0, -0.2, 0.2, 1.0, &
-1.0, -0.2, 0.2, 1.0, -1.0, -0.2, 0.2, 1.0]
scp(:)%z = [ 1.0, 1.0, -2.0, -2.0, 1.0, 1.0, -2.0, -2.0, &
3.0, 3.0, 1.0, 1.0, 3.0, 3.0, 1.0, 1.0]
U = [0.0_wp,0.0_wp,0.0_wp,0.0_wp,1.0_wp,1.0_wp,1.0_wp,1.0_wp]
V = [0.0_wp,0.0_wp,0.0_wp,0.50_wp,1.0_wp,1.0_wp,1.0_wp]
!the vector making the third midpoint refinement for knot vector U
X=[0.125_wp, 0.25_wp, 0.375_wp, 0.5_wp, 0.625_wp, 0.75_wp, 0.875_wp]
!the vector making the second midpoint refinement for knot vector V
Y=[0.125_wp, 0.25_wp, 0.375_wp, 0.625_wp, 0.75_wp, 0.875_wp]
S = spl(dim=3, pd=2, p=[3,2], kXi=U, kEta=V, cp=scp)
surf1 = S
surf2 = S
! plot the initial control points
call surf1%plot(plotCP=T, labelCP=T, &
plotSpl=F, & !do not plot surface
terminal='png', &
fname="test_F5.9", &
plotOpt=["set view ,120"], & !set the view as in the book.
title="The control net of a (cubic x quadratic) surface" )
! the third midpoint refinement in the u-direction
call surf1%RefineKnotVect(X=X)
! plot the new control points
call surf1%plot(plotCP=T, labelCP=T, &
plotSpl=F, & !do not plot surface
terminal='png', &
fname="test_F5.17a", &
plotOpt=["set view ,120"], & !set the view as in the book.
title="The third midpoint refinement in the u-direction" )
! the second midpoint refinement in the v-direction
call surf2%RefineKnotVect(Y=Y)
! plot the new control points
call surf2%plot(plotCP=T, labelCP=T, &
plotSpl=F, & !do not plot surface
terminal='png', &
fname="test_F5.17b", &
plotOpt=["set view ,120"], & !set the view as in the book.
title="The second midpoint refinement in the v-direction" )
! the second refinement in the v-direction in addition to the third refinement
! in the u-direction. surf1 is already refined in the u-direction
call surf1%RefineKnotVect(Y=Y)
! plot the new control points after refinement in both direction
call surf1%plot(plotCP=T, labelCP=T, &
plotSpl=F, & !do not plot surface
terminal='png', &
fname="test_F5.17c", &
plotOpt=["set view ,120"], & !set the view as in the book.
title="The third refinement in the u-direction and second in the v-direction." )
pause
end program test_surface_refinement
The resulting plots are as follow,